package com.zhkj.crawl.walmartTest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhkj.crawl.config.jsoup.TrustSsl;
import com.zhkj.crawl.config.Constants;
import com.zhkj.crawl.config.OkHttpPool;
import com.zhkj.crawl.config.StringPool;
import okhttp3.*;
import org.apache.commons.io.FileUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.springframework.http.HttpHeaders;

import java.io.File;
import java.io.IOException;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class q {
    public static final String UA = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36";
    public static final String ipUrl = "https://www.ip.cn/api/index?ip=&type=0";
    private static final String HOST = "https://www.walmart.com";

    public static void main(String[] args) throws Exception {
        TrustSsl.trust();
        Authenticator.setDefault(new Authenticator() {
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(Constants.PROXY_USERNAME, Constants.PROXY_PASSWORD.toCharArray());
            }
        });

//		httpGET(HOST);
//		walmartTest();

        String itemId = "697273103";
        httpReqWalmart(itemId, 0);
    }

    private static void httpReqWalmart(String itemId, Integer deep) throws InterruptedException, IOException {
        String baseUrl = String.format("https://www.walmart.com/ip/seort/%s", itemId);
        String reqUrl = "https://www.walmart.com/orchestra/home/graphql";
        if(deep > 0){
            System.out.printf("retry %s\n", deep);
        }
        JSONObject ckJson = readCk();
        String ckStr = ckToStr(ckJson);

        String body = String.format("{\"query\":\"query GetAllSellerOffers( $itemId:String! $postalAddress:PostalAddress $storeFrontIds:[StoreFrontId]){product( itemId:$itemId postalAddress:$postalAddress storeFrontIds:$storeFrontIds ){allOffers{offerId offerType availabilityStatus fulfillmentType fulfillmentBadge sellerId catalogSellerId sellerName sellerDisplayName sellerType wfsEnabled hasSellerBadge priceInfo{currentPrice{price priceString}unitPrice{price priceString}}returnPolicy{returnable freeReturns returnWindow{value unitType}}shippingOption{slaTier availabilityStatus accessTypes deliveryDate maxDeliveryDate shipPrice{price priceString}}}}}\",\"variables\":{\"itemId\":\"%s\"}}\n", itemId);
        JSONObject jsonObject = JSON.parseObject(body);

//		HttpResponse response = HttpRequest.post(reqUrl)
        Connection.Response response = Jsoup.connect(reqUrl).method(Connection.Method.POST)
                .data("query", "query GetAllSellerOffers( $itemId:String! $postalAddress:PostalAddress $storeFrontIds:[StoreFrontId]){product( itemId:$itemId postalAddress:$postalAddress storeFrontIds:$storeFrontIds ){allOffers{offerId offerType availabilityStatus fulfillmentType fulfillmentBadge sellerId catalogSellerId sellerName sellerDisplayName sellerType wfsEnabled hasSellerBadge priceInfo{currentPrice{price priceString}unitPrice{price priceString}}returnPolicy{returnable freeReturns returnWindow{value unitType}}shippingOption{slaTier availabilityStatus accessTypes deliveryDate maxDeliveryDate shipPrice{price priceString}}}}}")
                .data("variables", String.format("{\"itemId\":\"%s\"}}", itemId))
                .header("Accept", "*/*")
                .header("Accept-Encoding", "gzip, deflate, br")
                .header("host", HOST.replace("https://", StringPool.EMPTY))
                .header("content-type", "application/json; charset=UTF-8")
                .header("origin", HOST)
                .header("referer", baseUrl)
                .header("user-agent", UA)
                .header("wm_mp", "true")
                .header("wm_page_url", baseUrl)
                .header("x-apollo-operation-name", "GetAllSellerOffers")
                .header("x-enable-server-timing", "1")
                .header("x-latency-trace", "1")
                .header("x-o-ccm", "server")
                .header("x-o-gql-query", "query GetAllSellerOffers")
                .header("x-o-market", "us")
                .header("x-o-platform", "rweb")
                .header("x-o-platform-version", "main-176-348925")
                .header("x-o-segment", "oaoh")
                .header("cookie", ckStr)
                .ignoreHttpErrors(true).ignoreContentType(true)
                .execute();
//		for (HttpCookie cookie : response.getCookies()) {
//			System.out.printf("cookie %s => %s\n", cookie.getName(), cookie.getValue());
//			ckJson.put(cookie.getName(), cookie.getValue());
//		}

        for (Map.Entry<String, String> entry : response.cookies().entrySet()) {
            System.out.printf("verify cookie %s => %s\n", entry.getKey(), entry.getValue());
            ckJson.put(entry.getKey(), entry.getValue());
        }

        writeCk(ckJson);

        int code = response.statusCode();
        String resultStr = response.body();
        JSONObject json = JSON.parseObject(resultStr);

        System.out.printf("本次结果：code: %s, result: %s\n", code, resultStr);

        if(code == 412 && ++deep < 3){
            String verifyUrl = HOST + json.getString("redirectUrl");
            System.out.printf("\nverifying... try %s %s\n", deep, verifyUrl);
            TimeUnit.SECONDS.sleep(2);
            httpGet(verifyUrl);
            httpReqWalmart(itemId, deep);
        }

    }


    private static String ckToStr(JSONObject ckJson) {
        StringBuilder ck = new StringBuilder();
        for (String s : ckJson.keySet()) {
            ck.append(String.format("%s=%s; ", s, ckJson.get(s)));
        }
        return ck.toString();
    }


    static String ckPath = "D:\\data\\logistics-group\\crawl-service\\src\\test\\resources\\walmart.ck";
    private static void writeCk(JSONObject ckJson) {
        try {
            FileUtils.writeStringToFile(new File(ckPath), ckJson.toString(), false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static JSONObject readCk() {
        try {
            String ck = FileUtils.readFileToString(new File(ckPath));
            return JSON.parseObject(ck);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new JSONObject();
    }

    private static void walmartTest() throws Exception{
        String itemId = "697273103";
        String baseUrl = String.format("https://www.walmart.com/ip/seort/%s", itemId);
        String proxyStr = "";
        OkHttpClient client = OkHttpPool.getOkHttpClient(proxyStr);
        Request request = new Request.Builder()
                .url(baseUrl)
                .header(HttpHeaders.REFERER, baseUrl)
                .header(HttpHeaders.USER_AGENT, UA)
                .header("service-worker-navigation-preload", "true")
                .header("upgrade-insecure-requests", "1")
                .get().build();
        Response response = client.newCall(request).execute();
        int code = response.code();
        System.out.printf("first code: %s\n", code);

        System.out.println(walmartOkHttp(itemId, 0));
    }

    private static String walmartOkHttp(String itemId, Integer deep) throws IOException, InterruptedException {
        String baseUrl = String.format("https://www.walmart.com/ip/seort/%s", itemId);
        if(deep > 0){
            System.out.printf("retry %s\n", deep);
        }
        Headers.Builder headers = new Headers.Builder();
        headers
                .add("Accept", "*/*")
                .add("Accept-Encoding","gzip, deflate, br")
                .add("host", HOST.replace("https://", StringPool.EMPTY))
                .add("content-type", "application/json")
                .add("origin", HOST)
                .add("referer", baseUrl)
                .add("user-agent", UA)
                .add("wm_mp", "true")
                .add("wm_page_url", baseUrl)
                .add("x-apollo-operation-name", "GetAllSellerOffers")
                .add("x-enable-server-timing", "1")
                .add("x-latency-trace", "1")
                .add("x-o-ccm", "server")
                .add("x-o-gql-query", "query GetAllSellerOffers")
                .add("x-o-market", "us")
                .add("x-o-platform", "rweb")
                .add("x-o-platform-version", "main-176-348925")
                .add("x-o-segment", "oaoh")
        ;

        String body = String.format("{\"query\":\"query GetAllSellerOffers( $itemId:String! $postalAddress:PostalAddress $storeFrontIds:[StoreFrontId]){product( itemId:$itemId postalAddress:$postalAddress storeFrontIds:$storeFrontIds ){allOffers{offerId offerType availabilityStatus fulfillmentType fulfillmentBadge sellerId catalogSellerId sellerName sellerDisplayName sellerType wfsEnabled hasSellerBadge priceInfo{currentPrice{price priceString}unitPrice{price priceString}}returnPolicy{returnable freeReturns returnWindow{value unitType}}shippingOption{slaTier availabilityStatus accessTypes deliveryDate maxDeliveryDate shipPrice{price priceString}}}}}\",\"variables\":{\"itemId\":\"%s\"}}\n", itemId);
        JSONObject jsonObject = JSON.parseObject(body);

        Request request = new Request.Builder()
                .url("https://www.walmart.com/orchestra/home/graphql")
                .post(RequestBody.create(MediaType.parse("application/json"), jsonObject.toString()))
                .headers(headers.build())
                .build();

        String proxyStr = "";
        OkHttpClient client = OkHttpPool.getOkHttpClient(proxyStr);
        Response response = client.newCall(request).execute();
        String ret = response.body().string();
        int code = response.code();
        if(code != 200){
            System.err.printf("func code: %s, body: %s\n", code, ret);
            if(412 == code){
//				JSONObject json = JSON.parseObject(ret);
//				String redirectUrl = HOST + json.getString("redirectUrl");
//				jump2captcha(redirectUrl);

//				String blockScript = HOST + json.getString("blockScript");
//				jump2captcha(blockScript);
                TimeUnit.SECONDS.sleep(1);
            }
            if(++deep < 2){
                TimeUnit.SECONDS.sleep(1);
                return walmartOkHttp(itemId, deep);
            }
        }

        return ret;
    }

    private static void httpGet(String url) throws IOException {
        JSONObject ckJson = readCk();
        String ckStr = ckToStr(ckJson);

        Connection.Response response = Jsoup.connect(url).method(Connection.Method.GET)
//		HttpResponse response = HttpRequest.get(url)
                .header("Accept", "*/*")
                .header("Accept-Encoding", "gzip, deflate, br")
                .header("host", HOST.replace("https://", StringPool.EMPTY))
                .header("origin", HOST)
                .header("user-agent", UA)
                .header("cookie", ckStr).execute();
//				.execute();
        for (Map.Entry<String, String> entry : response.cookies().entrySet()) {
            System.out.printf("verify cookie %s => %s\n", entry.getKey(), entry.getValue());
            ckJson.put(entry.getKey(), entry.getValue());
        }
//		for (HttpCookie cookie : response.getCookies()) {
//			System.out.printf("verify cookie %s => %s\n", cookie.getName(), cookie.getValue());
//			ckJson.put(cookie.getName(), cookie.getValue());
//		}
        writeCk(ckJson);

        System.out.printf("verify code: %s\n", response.statusCode());
    }

    private static void httpGET(String url){
        try {
            OkHttpClient client = OkHttpPool.getOkHttpClient("f");
            Request request = new Request.Builder()
                    .url(url)
                    .header(HttpHeaders.REFERER, url)
                    .header(HttpHeaders.USER_AGENT, UA)
                    .header("service-worker-navigation-preload", "true")
                    .header("upgrade-insecure-requests", "1")
                    .get().build();
            Response response = client.newCall(request).execute();
            String ret = response.body().string();
            //ret = ret.length() < 200 ? ret : "";
            Headers headers = response.headers();
            System.out.printf("%s http code: %s content: %s\n", url.replace(HOST, StringPool.EMPTY), response.code(), ret);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
